<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <style>
    #test {
      width: 100px;
      height: 100px;
      background-color: cadetblue;
      position: absolute;
      top: 0;
      left: 0;
    }
  </style>
</head>

<body>
  <div id="test"></div>
  <script>
    document.getElementById('test').onclick = function () {
      this.myAnimation({ left: 300, height: 20, width: 20 }, 1000);
    }
    function getStyle(dom, attr) {
      if (window.getComputedStyle) {
        return window.getComputedStyle(dom, null)[attr];
      } else {
        return dom.currentStyle[attr];
      }
    }
    // function startMove(dom, options) {
    //   clearInterval(dom.timer);
    //   var speed = null;
    //   var cur = null;
    //   var stop = true;
    //   dom.timer = setInterval(function () {
    //     for (var attr in options) {
    //       if (attr === 'opacity') {
    //         cur = parseFloat(getStyle(dom, attr)) * 100;
    //       } else {
    //         cur = parseInt(getStyle(dom, attr));
    //       }
    //       speed = attr === 'opacity' ? (options[attr] * 100 - cur) / 8 : (options[attr] - cur) / 8;
    //       speed = speed > 0 ? Math.ceil(speed) : Math.floor(speed);
    //       if (attr === 'opacity') {
    //         dom.style[attr] = (cur + speed) / 100;
    //       } else {
    //         dom.style[attr] = cur + speed + 'px';
    //       }
    //       stop = attr === 'opacity' ? cur === options[attr] * 100 : cur === options[attr];
    //       if (stop) {
    //         clearInterval(dom.timer);
    //       }
    //     }
    //   }, 1000 / 60);
    // }


    window.requestAniFrame = (function () {
      return window.requestAnimationFrame ||
        window.webkitRequestAnimationFrame ||
        window.mozRequestAnimationFrame ||
        window.oRequestAnimationFrame ||
        window.msRequestAnimationFrame ||
        function (callback) {
          setTimeout(callback, 1000 / 60);
        }
    })();

    window.cancelAnimation = (function () {
      return window.cancelAnimationFrame ||
        window.webkitCancelAnimationFrame ||
        window.mozCancelAnimationFrame ||
        window.msCancelAnimationFrame ||
        window.oCancelAnimationFrame ||
        function (id) {
          clearTimeout(id);
        }
    })();
    // 作业 加入opacity
    Element.prototype.myAnimation = function (options, time, easing, fun, callback) {
      var _that = this;
      var startTime = + new Date();
      var easingObj = {
        easeIn(time) {
          return time ** 2
        },
        shak(time) {
          if (time < 0.6) {
            return (time / 0.6) ** 2
          } else {
            return Math.sin((time - 0.6) * ((3 * Math.PI) / 0.4)) * 0.2 + 1
          }
        }
      }

      for (var attr in options) {
        var cur = parseInt(getStyle(_that, attr));
        var diff = options[attr] - cur;
        console.log(cur, diff)
        window.requestAniFrame(loop(attr, cur, diff));
      }
      function ani(attr, val) {
          _that.style[attr] = cur + val + 'px';
      }
      function loop(attr, cur, diff) {
        return function () {
          var timer = window.requestAniFrame(loop(attr, cur, diff));
          var passTime = + new Date() - startTime;
          var per = passTime / time;
          if (per >= 1) {
            per = 1;
            cancelAnimation(timer);
          }
          var num = typeof easingObj[easing] === 'function' ? easingObj[easing](per) : per;
          var speed = num * diff;

          ani(attr, speed);
        }
      }
    }
  </script>
</body>

</html>